import { LoggerService } from '@/common/logger/logger.service';
import { HttpService } from '@nestjs/axios';
import { Injectable, OnModuleInit } from '@nestjs/common';
import { AxiosRequestConfig } from 'axios';
import { nanoid } from 'nanoid';
import * as qs from 'querystring';

@Injectable()
export class HttpClientService implements OnModuleInit {
  constructor(
    private readonly loggerService: LoggerService,
    private readonly httpService: HttpService,
  ) {}

  onModuleInit() {
    this.httpService.axiosRef.interceptors.request.use(
      (req) => {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        req.traceId = nanoid();
        this.loggerService.info(
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          // @ts-ignore
          `request: [${req.traceId}] ${req.method?.toUpperCase() ?? 'GET'} ${
            req.url
          }
         query: ${req.params ? `?${qs.stringify(req.params)}` : '--'}
         body: ${req.data ? JSON.stringify(req.data, null, 4) : '--'}
        `,
          HttpClientService.name,
        );
        return req;
      },
      (error) => {
        this.loggerService.error(error, HttpClientService.name);
        return Promise.reject(error);
      },
    );

    this.httpService.axiosRef.interceptors.response.use(
      (res) => {
        this.loggerService.info(
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          // @ts-ignore
          `response: [${res.config.traceId}] ${
            res.config.method?.toUpperCase() ?? 'GET'
          } ${res.config.url}
          body: ${res.data ? JSON.stringify(res.data, null, 4) : '--'}
        `,
          HttpClientService.name,
        );
        return res;
      },
      (error) => {
        this.loggerService.error(error, HttpClientService.name);
        return Promise.reject(error);
      },
    );
  }

  request<T>(config: AxiosRequestConfig) {
    return this.httpService.request<T>(config).toPromise();
  }
}
